package cn.itbaizhan.tyut.exam.sys.servlets;


import cn.itbaizhan.tyut.exam.common.PageControl;
import cn.itbaizhan.tyut.exam.common.Pager;
import cn.itbaizhan.tyut.exam.common.Tools;
import cn.itbaizhan.tyut.exam.model.*;
import cn.itbaizhan.tyut.exam.sys.services.impl.PaperService;
import cn.itbaizhan.tyut.exam.sys.services.impl.StudentpaperService;
import cn.itbaizhan.tyut.exam.sys.services.impl.UserService;
import cn.itbaizhan.tyut.exam.sys.services.interfaces.IPaperService;
import cn.itbaizhan.tyut.exam.sys.services.interfaces.IStudentpaperService;
import cn.itbaizhan.tyut.exam.sys.services.interfaces.IUserService;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@MultipartConfig
public class UserServlet extends HttpServlet {

    IUserService service = new UserService();
    IPaperService paperService = new PaperService();
    IStudentpaperService spServece = new StudentpaperService();

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String cmd = request.getParameter("cmd");
        if (cmd.equals("paperlist")) {
            index(request, response);
        } else if (cmd.equals("login")) {
            login(request, response);
        } else if (cmd.equals("init")) {
            initpage(request, response);
        } else if (cmd.equals("logout")) {
            logout(request, response);
        } else if (cmd.equals("list")) {
            list(request, response);
        } else if (cmd.equals("add")) {
            add(request, response);
        } else if (cmd.equals("toedit")) {
            toedit(request, response);
        } else if (cmd.equals("edit")) {
            edit(request, response);
        } else if (cmd.equals("toeditpwd")) {
            toeditpwd(request, response);
        } else if (cmd.equals("editpwd")) {
            editpwd(request, response);
        } else if (cmd.equals("paper")) {
            paper(request, response);
        } else if (cmd.equals("stulogin")) {
            stulogin(request, response);
        } else if (cmd.equals("answer")) {
            answer(request, response);
        } else if (cmd.equals("stuRegist")) {
            stuRegist(request, response);
        } else if (cmd.equals("import-students")) {
            stuImports(request, response);
        }
    }

    /*private void stuImports(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Part filePart = null; // 获取名为"excelFile"的Part
        try {
            filePart = request.getPart("excelFile");
            InputStream inputStream = filePart.getInputStream();
            List<Map<String, String>> failures = new ArrayList<>();
            ExcelReaderBuilder readerBuilder = EasyExcel.read(inputStream, Stu.class, new AnalysisEventListener<Stu>() {
                @Override
                public void invoke(Stu student, AnalysisContext analysisContext) {
                    int result = saveStudent(student);
                    if (result == 1) {
                        Map map = new HashMap();
                        map.put("username", student.getName());
                        map.put("truename", student.getTrueName());
                        map.put("msg", "用户名重复");
                        failures.add(map);
                    } else if (result == 2) {
                        Map map = new HashMap();
                        map.put("username", student.getName());
                        map.put("truename", student.getTrueName());
                        map.put("msg", "添加失败");
                        failures.add(map);
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    if (!failures.isEmpty()) {
                        request.setAttribute("failures", failures);
                    }
                }

                @Override
                public void onException(Exception exception, AnalysisContext context) throws Exception {
                    // 当转换数据时发生异常，此处可以进行处理
                    if (exception instanceof ExcelDataConvertException) {
                        ExcelDataConvertException excelException = (ExcelDataConvertException) exception;
                        CellData<?> cellData1 = excelException.getCellData();
                        ReadCellData cellData = (ReadCellData) cellData1;
                        String errorMessage = String.format("转换第%s行第%s列数据时出错，原始值：%s",
                                excelException.getRowIndex(), excelException.getColumnIndex(), cellData.getStringValue());
                        System.err.println(errorMessage);
                    }
                }
            });
            readerBuilder.sheet(0).doRead();
            PageControl pc = new PageControl();
            Integer currindex = 1;
            if (request.getParameter("index") != null) {
                currindex = Integer.parseInt(request.getParameter("index"));
            }
            pc.setCurrentindex(currindex);
            Sysuser user = new Sysuser();
            Pager<Sysuser> pager = service.list(user, pc);
            request.setAttribute("pager", pager);
        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("msg", "文件读取失败！");
        }
        request.getRequestDispatcher("/sys/user/list.jsp").forward(request, response);
    }*/
    private void stuImports(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Part filePart = null; // 获取名为"excelFile"的Part
        try {
            filePart = request.getPart("excelFile");
            InputStream inputStream = filePart.getInputStream();
            List<Map<String, String>> failures = new ArrayList<>();

            Workbook sheets = WorkbookFactory.create(inputStream);
            Sheet sheet = sheets.getSheetAt(0);
            // 读取标题行并创建映射
            Row headerRow = sheet.getRow(0);
            Map<String, Integer> headerMap = new HashMap<>();
            for (Cell cell : headerRow) {
                headerMap.put(cell.getStringCellValue(), cell.getColumnIndex());
            }

            // 从第二行开始读取数据
            for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
                Row row = sheet.getRow(rowNum);
                if (row == null) {
                    continue;
                }
                Stu stu = new Stu();

                // 根据标题映射来填充Stu对象
                if (headerMap.containsKey("用户名")) {
                    Cell nameCell = row.getCell(headerMap.get("用户名"));
                    if (nameCell != null) {
                        stu.setName(nameCell.getStringCellValue().trim());
                    }
                }
                if (headerMap.containsKey("密码")) {
                    Cell passCell = row.getCell(headerMap.get("密码"));
                    if (passCell != null) {
                        stu.setPassword(passCell.getStringCellValue().trim());
                    }
                }
                if (headerMap.containsKey("姓名")) {
                    Cell trueNameCell = row.getCell(headerMap.get("姓名"));
                    if (trueNameCell != null) {
                        stu.setTrueName(trueNameCell.getStringCellValue().trim());
                    }
                }
                int result = saveStudent(stu);
                int rowCount = rowNum + 1;
                if (result == 1) {
                    Map map = new HashMap();
                    map.put("cell", "第" + rowCount + "行");
                    map.put("username", stu.getName());
                    map.put("truename", stu.getTrueName());
                    map.put("msg", "用户名重复");
                    failures.add(map);
                } else if (result == 2) {
                    Map map = new HashMap();
                    map.put("cell", "第" + rowCount + "行");
                    map.put("username", stu.getName());
                    map.put("truename", stu.getTrueName());
                    map.put("msg", "添加失败");
                    failures.add(map);
                } else if (result == 3) {
                    Map map = new HashMap();
                    map.put("cell", "第" + rowCount + "行");
                    map.put("username", stu.getName());
                    map.put("truename", stu.getTrueName());
                    map.put("msg", "用户名、密码、姓名不可以为空");
                    failures.add(map);
                }
            }
            if (!failures.isEmpty()) {
                request.setAttribute("failures", failures);
            }
            PageControl pc = new PageControl();
            Integer currindex = 1;
            if (request.getParameter("index") != null) {
                currindex = Integer.parseInt(request.getParameter("index"));
            }
            pc.setCurrentindex(currindex);
            Sysuser user = new Sysuser();
            Pager<Sysuser> pager = service.list(user, pc);
            request.setAttribute("pager", pager);
            if (failures.isEmpty())
                request.setAttribute("msg", "导入成功！");

        } catch (Exception e) {
            e.printStackTrace();
            request.setAttribute("msg", "文件读取失败！");
        }
        request.getRequestDispatcher("/sys/user/list.jsp").forward(request, response);
    }

    // 0：成功 1：重复用户名 2：添加失败
    private int saveStudent(Stu student) {
        if (null == student.getName() || null == student.getPassword() || null == student.getTrueName()) {
            return 3;
        }
        Sysuser user = new Sysuser();
        user.setRoleid(1); // 学生
        user.setRolename("学生");
        user.setUserstate(1);
        user.setUsertruename(student.getTrueName());
        user.setUsername(student.getName());
        user.setUserpwd(student.getPassword());
        if (service.selectByUsername(student.getName()) != null) {
            return 1;
        }

        int addCount = service.add(user);
        return addCount == 1 ? 0 : 2;
    }

    /**
     * 跳转首页
     *
     * @param request
     * @param response
     */
    private void index(HttpServletRequest request, HttpServletResponse response) {
        Paper paper = new Paper();
        //String pname = request.getParameter("pname");
        //paper.setPname(pname);
        List<Paper> papers = paperService.list(paper);
        request.setAttribute("papers", papers);
        try {
            request.getRequestDispatcher("/user/index.jsp").forward(request, response);
        } catch (ServletException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 修改用户功能
     *
     * @param request
     * @param response
     */
    private void edit(HttpServletRequest request, HttpServletResponse response) {
        // TODO Auto-generated method stub
        Sysuser user = new Sysuser();

        try {
            BeanUtils.populate(user, request.getParameterMap());
            Integer rtn = service.edit(user);
            if (rtn > 0) {
                response.sendRedirect(Tools.Basepath(request, response) + "sys/user?cmd=list");
            } else {
                request.setAttribute("msg", "保存用户失败！");
                request.getRequestDispatcher("/sys/user/edit.jsp").forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 用户初始化修改页面
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     * @throws IOException
     * @throws ServletException
     */
    private void toedit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        Sysuser user = new Sysuser();
        user.setUserid(Integer.parseInt(request.getParameter("id")));
        user = service.detail(user);
        if (user != null) {
            request.setAttribute("item", user);
            request.getRequestDispatcher("/sys/user/edit.jsp").forward(request, response);
        } else {
            request.setAttribute("msg", "需要修改的用户不存在。");
            request.getRequestDispatcher("/error.jsp").forward(request, response);
        }
    }

    /**
     * 修改用户密码功能
     *
     * @param request
     * @param response
     */
    private void editpwd(HttpServletRequest request, HttpServletResponse response) {
        // TODO Auto-generated method stub
        Sysuser user = new Sysuser();

        try {
            BeanUtils.populate(user, request.getParameterMap());
            Integer rtn = service.editpwd(user);
            if (rtn > 0) {
                response.sendRedirect(Tools.Basepath(request, response) + "sys/user?cmd=list");
            } else {
                request.setAttribute("msg", "保存用户失败！");
                request.getRequestDispatcher("/sys/user/editpwd.jsp").forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 用户初始化密码修改页面
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     * @throws IOException
     * @throws ServletException
     */
    private void toeditpwd(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        Sysuser user = new Sysuser();
        user.setUserid(Integer.parseInt(request.getParameter("id")));
        user = service.detail(user);
        if (user != null) {
            request.setAttribute("user", user);
            request.getRequestDispatcher("/sys/user/editpwd.jsp").forward(request, response);
        } else {
            request.setAttribute("msg", "需要修改的用户不存在。");
            request.getRequestDispatcher("/error.jsp").forward(request, response);
        }
    }

    /**
     * 新增用户
     *
     * @param request
     * @param response
     */
    private void add(HttpServletRequest request, HttpServletResponse response) {
        // TODO Auto-generated method stub
        Sysuser user = new Sysuser();
        try {
            BeanUtils.populate(user, request.getParameterMap());
            Integer rtn = service.add(user);
            if (rtn > 0) {
                response.sendRedirect(Tools.Basepath(request, response) + "sys/user?cmd=list");
            } else {
                request.setAttribute("msg", "添加用户失败或请不要再重复添加");
                request.getRequestDispatcher("/sys/user/add.jsp").forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取用户列表
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     * @throws IOException
     * @throws ServletException
     */
    private void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        String sname = request.getParameter("sname");
        Sysuser user = new Sysuser();
        if (sname != null && !sname.equals("")) {
            user.setUsername("%" + sname + "%");
        }

        PageControl pc = new PageControl();
        Integer currindex = 1;
        if (request.getParameter("index") != null) {
            currindex = Integer.parseInt(request.getParameter("index"));
        }
        pc.setCurrentindex(currindex);
        //pc.setPagesize(5);

        Pager<Sysuser> pager = service.list(user, pc);
        request.setAttribute("pager", pager);
        request.getRequestDispatcher("/sys/user/list.jsp").forward(request, response);

    }

    /**
     * 注销
     *
     * @param request
     * @param response
     * @throws IOException
     */
    private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {

        HttpSession session = request.getSession();
        session.removeAttribute("user");
        response.sendRedirect(Tools.Basepath(request, response) + "login.jsp");
    }

    /**
     * 初始化主页
     *
     * @param request
     * @param response
     */
    private void initpage(HttpServletRequest request, HttpServletResponse response) {

        HttpSession session = request.getSession(true);
        Sysuser user = (Sysuser) session.getAttribute("user");
        List<SysFunction> list = service.initpage(user);
        try {
            request.setAttribute("list", list);
            RequestDispatcher rds = request.getRequestDispatcher("/index.jsp");
            rds.forward(request, response);
            return;
            //request.getRequestDispatcher("/index.jsp").forward(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 用户登陆
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        Sysuser user = new Sysuser();
        user.setUsername(request.getParameter("username"));
        user.setUserpwd(request.getParameter("userpwd"));

        user = service.login(user);
        if (user == null) {
            request.setAttribute("msg", "用户名密码错误");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        } else {
            HttpSession session = request.getSession(true);
            session.setAttribute("user", user);
            initpage(request, response);
            //request.getRequestDispatcher("/sys/user?cmd=init").forward(request, response);
        }
    }

    /**
     * 学生获取试题内容
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void paper(HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {
        Paper paper = new Paper();
//		String pname = new String(request.getParameter("pname").getBytes("iso-8859-1"), "utf-8");
        String pname = new String(request.getParameter("pname"));
        paper.setPname(pname);
        List<Subject> subjects = paperService.subjectlist(paper);
        Map<Integer, List<Subject>> subjectMap = new HashMap<>();
        for (Subject subject : subjects) {
            List<Subject> list = subjectMap.get(subject.getType());
            if (list == null) {
                list = new ArrayList<>();
                subjectMap.put(subject.getType(), list);
            }
            list.add(subject);
        }
//		request.setAttribute("subjectMap", subjectMap);
        request.setAttribute("subjects", subjects);
        request.setAttribute("pname", pname);
        request.getRequestDispatcher("/user/paper/paper.jsp").forward(request, response);
    }

    /**
     * 提交回答问题
     *
     * @param request
     * @param response
     * @throws UnsupportedEncodingException
     */
    private void answer(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        //JSONArray json = JSONArray.fromObject(personstr);
        // TODO Auto-generated method stub
        // System.out.println(request.getParameterMap());
        String pname = new String(request.getParameter("pname").getBytes("utf-8"), "utf-8");
        Studentpaper studentpaper = new Studentpaper();
        try {
            BeanUtils.populate(studentpaper, request.getParameterMap());
            studentpaper.setPname(pname);
            Integer rtn = spServece.addPaper(studentpaper);
            if (rtn > 0) {
                //response.sendRedirect(Tools.Basepath(request, response)+"sys/user?cmd=list");
            } else {
//				request.setAttribute("msg", "保存用户失败");
//				request.getRequestDispatcher("/sys/user/add.jsp").forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 学生登陆
     *
     * @param request
     * @param response
     * @throws IOException
     * @throws ServletException
     */
    private void stulogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        Sysuser user = new Sysuser();
        user.setUsername(request.getParameter("username"));
        user.setUserpwd(request.getParameter("userpwd"));
        user = service.stulogin(user);
        if (user == null) {
            request.setAttribute("msg", "用户名密码错误");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        } else {
            HttpSession session = request.getSession(true);
            session.setAttribute("user", user);
            session.setAttribute("userid", user.getUserid());
            index(request, response);
            //	request.getRequestDispatcher("/sys/user?cmd=init").forward(request, response);
        }
    }

    /**
     * 学生注册
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    private void stuRegist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String username = request.getParameter("username");
        String password = request.getParameter("userpwd");
        String confirmPass = request.getParameter("confirmpass");
        String truename = request.getParameter("truename");
        if (username == null || username.trim().equals("")) {
            request.setAttribute("msg", "用户名不能为空");
            request.getRequestDispatcher("/regist.jsp").forward(request, response);
            return;
        }
        if (password == null || password.trim().equals("")) {
            request.setAttribute("msg", "密码不能为空");
            request.getRequestDispatcher("/regist.jsp").forward(request, response);
            return;
        }
        if (confirmPass == null || confirmPass.trim().equals("")) {
            request.setAttribute("msg", "确认密码不能为空");
            request.getRequestDispatcher("/regist.jsp").forward(request, response);
            return;
        }
        if (truename == null || truename.trim().equals("")) {
            request.setAttribute("msg", "真实姓名不能为空");
            request.getRequestDispatcher("/regist.jsp").forward(request, response);
            return;
        }
        if (!password.equals(confirmPass)) {
            request.setAttribute("msg", "两次输入密码不一致");
            request.getRequestDispatcher("/regist.jsp").forward(request, response);
            return;
        }

        Sysuser user = new Sysuser();
        user.setUsername(username);
        user.setUserpwd(password);
        user.setRoleid(1); // 1:学生
        user.setRolename("学生");
        user.setUsertruename(truename);
        user.setUserstate(1);
        if (service.selectByUsername(username) != null) {
            request.setAttribute("msg", "用户名已存在");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
            return;
        }
        Integer addCount = service.add(user);
        if (addCount == 1) {
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        } else {
            request.setAttribute("msg", "添加用户失败或请不要再重复添加");
        }
    }
}
